package main

import (
	"flag"
	"fmt"
	"io"
	"net"
	"os"
)

type Client struct {
	ServerIp   string
	ServerPort int
	Name       string
	conn       net.Conn
	// 当前客户端的模式
	flag 		int
}
// 处理server回应的消息
// 直接显示到标准输出即可
func (client *Client) handleResponse(){
// 把conn的内容复制到控制台的输出流
// 永久阻塞监听
io.Copy(os.Stdout, client.conn)

}
func (client *Client) SelectUser(){
	sendMsg:="who\n"
	_,err := client.conn.Write([]byte(sendMsg))
	if err!=nil{
		fmt.Println("》》》conn write err",err.Error())
		return
	}
}
func  (client *Client) PrivateChat(){
	var remoteName string
	var chatMsg string
client.SelectUser()
fmt.Println("》》》请输入聊天对象的用户名,输入exit退出:")
fmt.Scanln(&remoteName)
for remoteName!= "exit" && len(remoteName)>0{

		fmt.Println("》》》请输入聊天内容，输入exit退出")
		fmt.Scanln(&chatMsg)
		for chatMsg!="exit"{
		if  len(chatMsg)>0{
			sendMsg:="to|"+remoteName+"|"+chatMsg+"\n\n"
			_,err:=client.conn.Write([]byte(sendMsg))
			if err !=nil{
				fmt.Println("》》》conn write err",err.Error())
				break
			}
		}
		fmt.Println("》》》请输入聊天内容，输入exit退出")
		fmt.Scanln(&chatMsg)
	}
	client.SelectUser()
	fmt.Println("》》》请输入聊天对象的用户名,输入exit退出:")
	fmt.Scanln(&remoteName)
}

}
func (client *Client) PublicChat(){
	var myMsg string
	// 提示用户输入消息
	fmt.Println("》》》请输入聊天内容，输入exit退出")
	// 发给服务器
	fmt.Scanln(&myMsg)
	for myMsg!= "exit"{
		if len(myMsg)>0{
			_,err:=client.conn.Write([]byte(myMsg+"\n"))
			if err !=nil{
				fmt.Println("》》》conn write err",err.Error())
				break
			}
		}
		myMsg=""
		fmt.Println("》》》请输入聊天内容，输入exit退出")
		fmt.Scanln(&myMsg)
	}
	}
// 显示菜单
func (client *Client) menu() bool{
	var flag int
	fmt.Println("请输入要执行的选择数字0~3")
	fmt.Println("1.公聊模式")
	fmt.Println("2.私聊模式")
	fmt.Println("3.更新用户名")
	fmt.Println("0.退出")
	_,err:=fmt.Scanln(&flag)
	if err!=nil{
		fmt.Println("》》》》》》请输入合法的数字。。。")
		return false
	}
	if flag >=0 && flag<=3{
		client.flag = flag
		return true
	}else{
		fmt.Println("》》》》》》请输入合法的数字。。。")
		return false
	}
}

func (client *Client) Run(){
for client.flag!=0{
	// 正确选择数字后才能进入下一环节，否则一直显示菜单。
	for client.menu()!= true{

	}
	// 根据不同的flag执行对应的操作
	switch client.flag{
	case 1:
		client.PublicChat()
		// 公聊
	case 2:
		client.PrivateChat()
		// 私聊
	case 3:		
		client.UpdateName()
		// 改名
	}
}
}
func NewClient(serverIp string,serverPort int)*Client{
// 创建客户端对象
client := &Client{
	ServerIp: serverIp,
	ServerPort: serverPort,
	flag: 999,
}
// 链接server
conn,err:=net.Dial("tcp",fmt.Sprintf("%s:%d", serverIp,serverPort))
if err!=nil{
	fmt.Println("net conn failed",err.Error())
	return nil
	
}
client.conn = conn
// 返回对象
return client
}

var serverIp string
var serverPort int
// ./client -ip 127.0.0.1 -port 8888
func init(){
flag.StringVar(&serverIp,"ip","127.0.0.1","设置服务器IP地址(默认是127.0.0.1)")
flag.IntVar(&serverPort,"port",8888,"设置服务器端口(默认是8888)")
flag.Parse()
}

func (client *Client) UpdateName() bool{
	fmt.Println("》》》》》》请输入新的用户名")
	var newName string
	_,err:=fmt.Scanln(&newName)
	if err!=nil{
		fmt.Println("》》》》》》修改失败")
		return false
	}
	sendMsg:= "rename|"+newName+"\n"
	_,err = client.conn.Write([]byte(sendMsg))
	if err!= nil{
		fmt.Println("》》》》》》修改失败 connect.Write err")
		return false
	}
	client.Name = newName
	return true

}
func main(){

client:= NewClient(serverIp,serverPort)
if client == nil{
	fmt.Println("》》》》》》链接服务器失败。。。")
	return
}
// 单独开启一个goroutine去处理server的回执消息
go client.handleResponse()
fmt.Println(">>>>>>>>链接服务器成功")
client.Run()
}